#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef int SLDataType;
typedef struct ListNode
{
	SLDataType data;
	struct ListNode* next;
}ListNode;


ListNode* BuySListNode(const SLDataType data)
{
	ListNode* p = (ListNode*)malloc(sizeof(struct ListNode));
	if (NULL == p)
	{
		perror("SListNode");
		exit(-1);
	}
	p->data = data;
	p->next = NULL;

	return p;
}


void SListPrint(const ListNode* const  phead)
{
	const ListNode* p = phead;
	while (p)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("NULL\n");
}


void SListPushBack(ListNode** phead, const SLDataType data)
{
	assert(phead);

	ListNode* p = BuySListNode(data);
	if (NULL==*phead)
	{
		*phead = p;
	}
	else
	{
		ListNode* ptr = *phead;
		while (ptr->next)
		{
			ptr = ptr->next;
		}
		ptr->next = p;
	}
}


SLDataType SListPopBack(ListNode** phead)
{
	assert(phead);
	assert(*phead);

	SLDataType data;
	if (NULL == (*phead)->next)
	{
		data = (*phead)->data;
		free(*phead);
		*phead = NULL;
	}
	else
	{
		ListNode* p = *phead;
		while (p->next->next)
		{
			p = p->next;
		}
		data = p->next->data;
		free(p->next);
		p->next = NULL;
	}

	return data;
}


void SListPushFront(ListNode** phead,const SLDataType data)
{
	assert(phead);

	ListNode* p = BuySListNode(data);
	if (NULL == *phead)
	{
		*phead = p;
	}
	else
	{
		p->next = *phead;
		*phead = p;
	}
}


SLDataType SListPopFront(ListNode** phead)
{
	assert(phead);
	assert(*phead);

	SLDataType data;
	ListNode* p = *phead;
	data = (*phead)->data;
	*phead = (*phead) -> next;
	free(p);
	return data;
}


ListNode* SListNodeFind(const ListNode*const phead,const SLDataType data)
{
	assert(phead);

	const ListNode* p = phead;
	while (p)
	{
		if (p->data == data)
		{
			return (ListNode*)p;
		}
		p = p->next;
	}

	return NULL;
}


void SListInsertAfter(ListNode* const pos, const SLDataType data)
{
	assert(pos);
	ListNode* p = BuySListNode(data);
	p->next = pos->next;
	pos->next = p;
}


void SListInsert(ListNode** phead,ListNode* const pos, const SLDataType data)
{
	assert(phead);
	assert(*phead);
	assert(pos);

	ListNode* p = BuySListNode(data);
	if (*phead == pos)
	{
		p->next = *phead;
		*phead = p;
	}
	else
	{
		ListNode* ptr = *phead;
		while (ptr->next)
		{
			if (ptr->next == pos)
			{
				p->next = ptr->next;
				ptr->next = p;
				break;
			}
			ptr = ptr->next;
		}
	}
}


void SListEraseAfter(ListNode* const pos)
{
	assert(pos);
	if (NULL != pos->next)
	{
		ListNode* p = pos->next;
		pos->next = pos->next->next;
		free(p);
	}
}


void SListErase(ListNode** phead, ListNode* const pos)
{
	assert(phead);
	assert(*phead);
	assert(pos);

	if (pos == *phead)
	{
		*phead = (*phead)->next;
		free(pos);
	}
	else
	{
		ListNode* p = *phead;
		while (p->next)
		{
			if (pos == p->next)
			{
				p->next = p->next->next;
				free(pos);
				break;
			}
			p = p->next;
		}
	}
}


void SListDestory(ListNode* phead)
{
	while (phead)
	{
		ListNode* p = phead;
		phead = phead->next;
		free(p);
	}
}


void test()
{
	ListNode* plist = NULL;
	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);
	SListPushFront(&plist, 6);

	//SListPrint(plist);
	//SListPopFront(&plist);
	//SListPopFront(&plist);
	//SListPopFront(&plist);
	//SListPopFront(&plist);
	//SListPopFront(&plist);
	//SListPopFront(&plist);
	//
	ListNode* p = SListNodeFind(plist,5);
	//SListInsertAfter(p, 7);
	//SListPrint(plist);
	//SListInsert(&plist, p, 8);
	//
	SListPrint(plist);
	//SListEraseAfter(p);
	SListErase(&plist, p);
	SListErase(&plist, p);
	SListErase(&plist, p);
	SListErase(&plist, p);
	SListErase(&plist, p);
	SListErase(&plist, p);
	SListErase(&plist,p);
	SListPrint(plist);
	SListDestory(plist);
}


int main()
{
	test();
	
	return 0;
}